package top.huxy.redis.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @author aproz
 * @Date 2022/2/24
 */
@Slf4j
@Component(value = "checkRedisConnection")
@ConditionalOnClass({
        RedisOperations.class,
        GenericObjectPoolConfig.class
})
public class CheckRedisConnection implements ApplicationListener<ApplicationStartedEvent> {
    @Value("${spring.redis.host:localhost}")
    private String host;
    @Value("${spring.redis.port:6379}")
    private int port;
    @Value("${spring.redis.username:}")
    private String username;
    @Value("${spring.redis.password:}")
    private String password;
    @Value("${spring.redis.database:0}")
    private int database;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    ApplicationContext context;
    public static final byte RETRY_COUNT = 6;

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        log.info("redis配置,host={},port={},username={},password={},database={}", host, port, username, password, database);
        for (byte i = 1; ; i++) {
            try {
                redisTemplate.randomKey();
                log.info("redis 连接成功");
                ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) context;
                DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
                beanFactory.removeBeanDefinition("checkRedisConnection");
                break;
            } catch (Exception e) {
                if (i == RETRY_COUNT) {
                    log.error("redis连接失败,重试次数达到{}次,程序停止", i);
                    System.exit(0);
                }
                log.info("redis 连接失败,一秒后重连,重试次数{}", i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
